package unet

import (
	"strings"
	"net"
	"fmt"
)

func AllIPs() (ips []string, err error) {
	ips = make([]string, 0)

	ifaces, err := net.Interfaces()
	if err != nil {
		return ips, err
	}

	for _, item := range ifaces {
		if item.Flags & net.FlagUp == 0 {
			continue
		}
		if item.Flags & net.FlagLoopback != 0 {
			continue
		}

		// ignore docker and warden bridge
		if strings.HasPrefix(item.Name, "docker") || strings.HasPrefix(item.Name, "w-") {
			continue
		}
		addrs, e := item.Addrs()
		if e != nil {
			return ips, e
		}

		for _, addr := range addrs {
			var ip net.IP
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			}

			if ip == nil || ip.IsLoopback() {
				continue
			}

			ip = ip.To4()
			if ip == nil {
				continue // not an ipv4 address
			}

			ipStr := ip.String()
			ips = append(ips, ipStr)
		}
	}

	return ips, nil
}

func Intranet(ips []string) string {
	if len(filterMap) == 0 && len(ips) > 0 {
		return ips[0]
	}

	for _, item := range ips {
		for _, v := range filterMap {
			if v(item) {
				return item
			}
		}
	}

	return ""
}


var filterMap map[string]func(ip string) bool

func init()  {
	filterMap = make(map[string]func(ip string) bool)
}

// 判断内网本地ip地址的过滤器
// TODO: 待基于过滤器的条件去过滤
func RegisterParser(name string, filter func(ip string) bool) {
	if _, exist := filterMap[name]; exist {
		panic(fmt.Sprintf("filter already register for name: %s", name))
	}

	filterMap[name] = filter
	return
}